To derive a graph structure such as shown in 
figure~\ref{fig:query-graph} we need to match the user's
question with the metadata and data of the underlying 
structured data source and apply all configured natural language patterns.
In the beginning of this section, we briefly introduce the matching 
algorithms.%-- even though this is not the core of our paper. 
The last subsection contains a more detailed description on how natural language
patterns are configured and executed.

\begin{figure*}[htb]
\begin{program}[H]
{\footnotesize
\begin{verbatim}
1 :yearsBackWardsToDateRange
2   rdf:type features:NlpPattern;
3   rdfs:label "Computes the beginning and end date, given a time range in years"^^xsd:string;
4   nlp:outputVariables "yearsBack,rangeBegin,rangeEnd"^^xsd:string;
5   nlp:rule
6     "((<last>|..|<previous>)([OD yearsBack]<POS:Num>[/OD])?<STEM:year>)"^^xsd:string;    
7   nlp:computeVariablesWithScript """
8     var today = new Date(); var dd = today.getDate(); var yyyy = today.getFullYear();     	
9     rangeEnd =  calculateEnd(dd,mm,yyyy);
10    rangeBegin = calculateStart(dd,mm,yyyy,yearsBack);
11		
12    function calculateEnd(dd,mm,yyyy) {
13        return 	yyyy + '-' + mm + '-' + dd; 						   
14    }
15    function calculateStart(dd,mm,yyyy,yearsBack) {
16        return (yyyy-yearsBack) + '-01-01';							   
17    } """^^xsd:string ;      
18  nlp:appliesTo dataType:Date;
\end{verbatim}}
\caption[width=10cm]{Pattern to compute dates from `last 3 years'.}
\label{rule_example}
\end{program}
\vspace{-8mm}
\end{figure*}


\subsection{Matching Metadata and Data}

% The federated search platform used within our work to implement a 
% generic Q\&A framework consists of an abstract 
% Information Extraction Plugin for indexing RDF graphs and
% matching the user's question and the indexed data.
% It is used in the scenario presented to spot terms of the
% user profile and the data warehouse schema inside the users'
% question.
%
We use a state-of-the-art information extraction system (SAP BusinessObjects 
Text Analysis\texttrademark, a succesor of the system presented in 
\cite{DBLP:conf/trec/Hull99}) with a custom scoring function to match metadata
objects inside the user's question. 
As scoring function for evaluating individual matches 
 we adapted the scoring that we presented in 
 \cite{DBLP:conf/www/BrauerHHLNB10}. In a nutshell, it combines 
 TF-IDF like metrics with Levenshtein and punishes in addition
 matches where the length of a term in the metadata is much 
 longer than the string that occurs in the users' question. A 
 threshold on the score limits the number of matches
 that are considered for further processing.
 
 If a substring of the users' question was identified 
 as matching a term in the datasource's metadata (user profile or 
 schema), the component generates an annotation node in the parse
 graph. This node links the matched node and the question node
  (cf. figure~\ref{fig:query-graph}).   
 As discussed before, runtime metadata such as the
 offset, length and score of the match are stored as
 attributes of the annotation node. 
%
% \subsection{Matching Data}
% 
% Since replicating a data warehouse or any other large data source
% to RDF is not very efficient (in particular here, because we would
% only replicate the data for indexing), we use custom plugins
% that are operating close to the data to
% match the question's content and warehouse data.
% 
% For the BI use case, this means retrieving the database mapping from the
% abstraction layer of the data warehouse (e.g. retrieving the
% table and column storing the customer age) and calculating matches
% directly inside the database (in our case SAP HANA\texttrademark)
% using SQL-scripts. This functionality inside the database makes
% heavy use of the built-in full-text search capabilities.
% For scoring, we use basically the raw TF-IDF values, again
% with a threshold to filter the number of matches.
%
Matching dimension values (used for filters) works in a similar fashion. We did 
some optimizations by leveraging the full-text 
search capabilities of the underlying database. If a match
with some dimension value (e.g. `Palo Alto') occurs, the system creates an annotation 
 like for matched metadata, linking the question and the 
metadata node, to signal the system that a value 
for a dimension was identified. 
The difference between metadata annotations
mentioned above to the ones created for dimension values
is the annotation type which is assigned to the
annotation and the relation to the metadata node (i.e. `hasValue' instead of `matches').


\subsection{Natural Language Patterns}
\label{natural-language-patterns}

%A very powerful generic plugin for information extraction is the 
%one for handling complex natural language features. 
We developed a very powerful mechanism for natural language pattern,
which we like to introduce in more detail. It can be used to
implement custom functionality (e.g. range queries, top-$k$ queries
or custom vocabulary such as shown for ``middle-agged''
in figure~\ref{fig:running-example}) that goes beyond keyword-matching.  
%
As explained in the previous section, natural language patterns 
are configured using RDF (see listing~\ref{rule_example} for an example). The three main parts of a natural 
language patterns are:\\
%
\textbf{(1) Extraction Rules:} The basis for natural language
patterns are extraction rules. In our case we use the CGUL rule
language\footnote{\url{http://help.sap.com/businessobject/product_guides/boexir4/en/sbo401_ds_tdp_ext_cust_en.pdf}},
which can be executed using SAP BusinessObjects Text Analysis\texttrademark. It
bases similarly as CPSL~\cite{Appelt:1998:CPS:1119089.1119095} or
JAPE~\cite{Cunningham99jape:a} on the idea of \emph{cascading finite-state
grammars} meaning that extraction rules can be built in a cascading way. Thus
any other rule engine can be used for this purpose. We make heavy use of
built-in primitives for part-of-speech tagging, regular expressions and the
option to define and export variables (e.g. the `$5$' in `top 5'). Note, that a
rule might simply consist of a token or a phrase list, e.g. containing
`middle-aged'.\\
%
  \textbf{(2) Transformation Scripts:} Once a rule fired, exported
  variables may require some post-processing 
  %(i.e., a normalization  or transformation)
  , e.g. to transform `15,000' or `15k'
  into `$15000$', a expression that can be used within a
  structured query. In many cases there is also the need to compute
  additional variables. The most simple case for such functionality
   is to output  beginning and ending of the age range defined 
   by a term such as `middle-agged'. 
   To do additional computations and transformations,
  we allow to embed scripts inside a natural language pattern,
  which can consume output variables of the extraction rule and
  can define new variables as needed.\\
%
  \textbf{(3) Referenced Resources:} A rule is often specific for
  a resource in some metadata graph. For instance in 
  figure~\ref{fig:query-graph} the pattern
  for `AgeTerms' applies only to
  the dimension `Age', the `Context' pattern only to
  nodes within the user profile and other patterns apply only
  to certain data types (e.g. patterns for ranges to numerical 
  dimension values) --  which are also represented as nodes. 
  In order to restrict the  domain of patterns, 
  we allow to specify referenced resources. Later, we
  will detail how these references can be used in
  generating structured queries.
  
We can see an example natural language pattern in listing~\ref{rule_example}.
It does not match our running example question
to underline the power and flexibility of the described mechanism. It depicts
a pattern to compute from a phrase like `for the last 3 years' two
date expressions (namely beginning and ending date) that can be used in a 
structured query. The example pattern is presented in the 
Turtle RDF format\footnote{\url{http://www.w3.org/TeamSubmission/turtle/}}.
%, 
%which has certain advantages with respect to readibility 
%compared to the more often-used XML representation. 

The first line defines the URI of the pattern (i.e. the subject of all 
following properties). All remaining lines define the pattern's 
properties (in terms of predicates and objects). Line 2 and 3 
contain the type and description in the sense of RDF and RDF-Schema. 
In line 4 we define the variables that are output of the pattern, here 
\mbox{`yearsBack'} and the actual dates (\mbox{`rangeBegin'} and 
\mbox{`rangeEnd'}). 

The extraction rule is defined in line 5 and 6. It consists of 
some trigger words like `last' or `previous',
the exported number ({\footnotesize\verb?[OD]?} marks that the expression
between shall be exported, {\footnotesize\verb?<POS:Num>?} references the
part-of-speech tag for numbers) and the ending token `year' (and its stems).

Between line 7 and line 17 stands the script used to compute
the actual values for the variables `rangeBegin' and 
`rangeEnd'. We use JavaScript, because it can 
be executed easily in our host programming language (Java) and embed it 
into the RDF representation to store the rule definition and 
the transformation logic together. In the last line, we define
that this rule only applies to dimensions which have values of 
data type `Date'.

Once an extraction rule fired and the attached script has been 
evaluated, an annotation node in the parse graph 
 is created as shown in figure~\ref{fig:query-graph}. The 
annotation node cares as properties runtime metadata such as
the match position (again offset and length inside the user's 
question), the annotation type and the computed variables.






% 
% 
% \subsection{Back Up}
% 
% First, a set of constraint templates are applied to the question.
% A constraint template is a set of constraints (some of them being optional)
% associated to translation rules.
% In the example~\ref{fig:running-example}, four \emph{groups} of successive
% tokens can be identified. Each group correspond to a set of constraints. The
% constraints are based on the set of \emph{annotations} from the parse tree. 
% The constraint are of different kinds: annotation's label (regular expression,
% or defined in a lexicon); position of the annotation in the question; \ldots
% \begin{itemize}
%   \item ``Top 5'': the constraints are displayed in the upper box in the figure. 
%   The inner boxes are the exported tokens. Thus, the exported tokens are:
%   ``order:Top''; ``nb\_items:5'' and ``measure:?'' where ``?'' means an optional
%   constraint (here there is no measure in this group). 
%   Rules defined in the domain-independant lexicon define how to interpret
%   ``Top'' at the translation step. 
%   \item ``middle-aged'': this constraint is defined in the domain-specific
%   lexicon, which defines how to interpret ``middle'' in the domain. It will be
%   rewritten as an explicit constraint (see
%   section~\ref{sec:running-example-normalization}).
%   \item ``in my city'': the keyword ``my'' triggers a rule involving contextual
%   information about the user. In this example, ``city'' is a dimesion, to be
%   rewritten as a filter corresponding to the city where is located the user.
% \end{itemize}
% The (database) entities recognized in this step (e.g. dimension, measures,
% filters) are indexed in a lexicon with their base and variant forms. 
% Thus, ``customers'' is recognized as the dimension ``[Customer]''. 
% 
% 
% \section{Normalization}
%  \label{sec:running-example-normalization}
% 
% Some expressions of natural language must be \emph{normalized}, i.e. rewritten
% such that they can be mapped with database elements.
% In the example~(\ref{eq:running-example}), the expression
% `\emph{middle-aged}' should be normalized in terms belonging to the dataset. 
% This expression can thus be rewritten for instance in ``of age 20 to 30''. The
% running example becomes then ``Top 5 \textit{of age 20 to 30} customers in my
% city$\star$''\footnote{This is not a well-formed English statement (it is
% marked with $\star$).}.
% The rewritten expression is then interpreted as a filter. 
% This example of normalization is domain-dependant, because ``middle-aged'' might
% have a various interpretations in different domain application. 
% Similarly, some expressions require run-time computations: for instance ``last
% year'' should be rewritten in ``2012''. This is also a domain-dependant
% normalization, because the beginning of the year differs with applications
% (e.g. fiscal year in the USA is from 1st October to 30 September while calendar
% year is from 1st January to 31st December).
% 
% There are other domain-independant examples (but language-dependant), like 
% ``1.5k'' to be rewritten in ``1,500''.
% Different normalization examples have been reported
% table~\ref{tab:normalization}.
% \begin{table}[!h]
% \centering
% \begin{tabular}{ll}\hline
% \multicolumn{1}{c}{\textbf{Expression}} &
% \multicolumn{1}{c}{\textbf{Rewriting}}\\\hline \hline
% ``$n$k'' & $n\times 1,000$\\\hline
% ``$n$M'' & $n\times 1,000,000$\\\hline
% ``$n$B'' & $n\times 1,000,000,000$\\\hline
% ``last year'' & $currentYear()-1$\\\hline
% \end{tabular}
% \caption{Rewritten expressions at the normalization step}
% \label{tab:normalization}
% \end{table}

\begin{figure*}[htb]
% \begin{center}
% \begin{tikzpicture}[remember picture]
% \tikzstyle{bigbox} = [draw, draw=black!20, rounded corners, rectangle]
% \tikzstyle{boxed} = [minimum height=0.8cm, draw=black!50, rounded corners,rectangle] 
% \tikzstyle{unboxed} = [minimum height=0.8cm,rounded corners,rectangle] 
% \tikzstyle{node}=[circle,minimum size=10pt,draw=black, font=\tiny ] 
% \tikzstyle{blind}=[]
% \tikzstyle{title} =[fill=white, text=black!80]
% \tikzstyle{edge} = [->,text=black]
% % user profile graph
%   
% 	\node[node,fill=yellow!30,font=\small](queryNode){Q};
%     %
%     \node[node,below of=queryNode,node distance=1.5cm, fill=yellow!10](dimAnnot1){A};
%     \node[unboxed,left of=dimAnnot1,node distance=.55cm](dimAnnotLabel1){?a3};
%     \path[edge,dashed] (queryNode) edge node {hasAnnotation} (dimAnnot1);    
%         
%     \node[node,below of=dimAnnot1,node distance=2.5cm, fill=red!10](dim1){D};
%     \node[unboxed,left of=dim1,node distance=.55cm](dimLabel1){?d1};
%     \path[edge,above=5pt] (dimAnnot1) edge node {matches} (dim1);
%     
%     \node[node,above left of=dim1, node distance=.8cm, fill=red!100](dim1Label){};
%     \node[unboxed,above of=dim1Label, node distance=.4cm](dim1LabelLabel){?dL1};
%     \path[edge,below=.1pt] (dim1) edge node {} (dim1Label);
%     
%     \node[node,below of=dim1,node distance=1.5cm, fill=red!10](dw){W};
%     \node[unboxed,below right of=dw,node distance=.5cm](dwLabel1){?w};
%     \path[edge] (dim1) edge node {} (dw);
%     
%     \node[node,left of=dw, node distance=1cm, fill=red!100](dwLabel){};
%     \node[unboxed,left of=dwLabel, node distance=.5cm](dwLabelLabel){?wL};
%     \path[edge,below=.1pt] (dw) edge node {} (dwLabel);
%     
%     \node[node,below of=dw,node distance=1.5cm, fill=red!10](dim4){D};
%     \node[unboxed,right of=dim4,node distance=.55cm](dimLabel4){?d4};
%     \path[edge,right=.1pt,dashed] (dim4) edge node {dimOf} (dw);
%     
%     \node[node,below of=dim4, node distance=.8cm, fill=red!100](dim4Label){};
%     \node[unboxed,right of=dim4Label, node distance=.55cm](dim4LabelLabel){?dL1};
%     \path[edge,below=.1pt] (dim4) edge node {} (dim4Label);
%     
%     \node[node,left of=dim4,node distance=1.2cm, fill=red!10](meas2){D};
%     \node[unboxed,left of=meas2,node distance=.6cm](measLabel2){?m2};
%     \path[edge,left=.1pt,dashed] (meas2) edge node {measOf} (dw);
%     
%     \node[node,below of=meas2, node distance=.8cm, fill=red!100](meas2Label){};
%     \node[unboxed,left of=meas2Label, node distance=.65cm](meas2LabelLabel){?mL1};
%     \path[edge,below=.1pt] (meas2) edge node {} (meas2Label);
%     
%     \node[node,left of=dimAnnot1, node distance=1.2cm, fill=yellow!10](measAnnot1){A};
%     \node[unboxed,left of=measAnnot1, node distance=.55cm](measAnnotLabel1){?a2};
%     \path[edge,dashed,above=.1pt] (queryNode) edge node {} (measAnnot1);
%     
%     \node[node,below of=measAnnot1,node distance=2.5cm, fill=red!10](meas1){M};
%     \node[unboxed,left of=meas1,node distance=.6cm](measLabel1){?m1};
%     \path[edge,above=5pt] (measAnnot1) edge node {matches} (meas1);
%     \path[edge,left=.1pt] (meas1) edge node {measOf} (dw);
%     
%     \node[node,above left of=meas1, node distance=.8cm, fill=red!100](meas1Label){};
%     \node[unboxed,above of=meas1Label, node distance=.4cm](meas1LabelLabel){?mL1};
%     \path[edge,below=.1pt] (meas1) edge node {} (meas1Label);
%         
%     \node[node,left of=measAnnot1, node distance=1.2cm, fill=yellow!10](topKAnnot){A};
%     \node[unboxed,left of=topKAnnot, node distance=.5cm](topKAnnotLabel){?a1};
%     \path[edge,dashed,above=.1pt] (queryNode) edge node {} (topKAnnot);
%     
%     \node[node,below left of=topKAnnot, node distance=1.2cm, fill=green!100](topKOrder){};
%     \node[unboxed,left of=topKOrder, node distance=.65cm](topKAnnotBeginLabel){?ord};
%     \path[edge,left=.1pt] (topKAnnot) edge node {order} (topKOrder);
%     
%     \node[node,above left of=topKAnnot, node distance=1.2cm, fill=green!100](topKNumber){};
%     \node[unboxed,left of=topKNumber, node distance=.5cm](topKAnnotEndLabel){?nb};
%     \path[edge,left=.1pt] (topKAnnot) edge node {number} (topKNumber);
%     
%     \node[node,below of=topKAnnot,node distance=2.5cm, fill=green!10](topK){P};
%     \node[unboxed,left of=topK,node distance=.65cm](topKLabel1){TopK};
%     \path[edge,above=5pt] (topKAnnot) edge node {matches} (topK);    
%     
%     \node[node,right of=dimAnnot1,node distance=1.2cm, fill=yellow!10](valueAnnot1){A};
%     \node[unboxed,left of=valueAnnot1,node distance=.55cm](valueAnnotLabel1){?a4};  
%     \path[edge,dashed] (queryNode) edge node {} (valueAnnot1);
%     
%             
%     \node[node,below left of=valueAnnot1, node distance=.8cm, fill=red!100](dim2Label){};
%     \node[unboxed,right of=dim2Label, node distance=.57cm](dim2LabelLabel){?vL2};
%     \path[edge,below=.1pt] (valueAnnot1) edge node {} (dim2Label);
%     
%     \node[node,below of=valueAnnot1,node distance=2.5cm, fill=red!10](dim2){D};
%     \node[unboxed,left of=dim2,node distance=.55cm](dimLabel2){?d2};
%     \path[edge,above=5pt] (valueAnnot1) edge node {valueOf} (dim2);
%     \path[edge,left=.1pt] (dim2) edge node {dimOf} (dw);
%     
%     \node[node,above left of=dim2, node distance=.8cm, fill=red!100](dim2Label){};
%     \node[unboxed,above of=dim2Label, node distance=.4cm](dim2LabelLabel){?dL2};
%     \path[edge,below=.1pt] (dim2) edge node {} (dim2Label);
%     
%     \node[node,right of=valueAnnot1,node distance=1.2cm, fill=yellow!10](profileAnnot1){A};
%     \node[unboxed,left of=profileAnnot1,node distance=.55cm](profileAnnotLabel1){?a5};  
%     \path[edge,dashed] (queryNode) edge node {} (profileAnnot1);
%     
%     \node[node,below of=profileAnnot1,node distance=2.5cm, fill=red!10](dim3){D};
%     \node[unboxed,left of=dim3,node distance=.55cm](dimLabel3){?d3};
%     \path[edge,above=5pt] (profileAnnot1) edge node {matches} (dim3);
%     \path[edge] (dim3) edge node {dimOf} (dw);
%     
%     \node[node,above left of=dim3, node distance=.8cm, fill=red!100](dim3Label){};
%     \node[unboxed,above of=dim3Label, node distance=.4cm](dim3LabelLabel){?dL3};
%     \path[edge,below=.1pt] (dim3) edge node {} (dim3Label);
%     
%     \node[node,below of=dim3,node distance=1.5cm, fill=blue!10](profile){?};
%     \node[unboxed,left of=profile,node distance=1.1cm](profileLabel){?profileItem};
%     \path[edge,right=.1pt] (dim3) edge node {occursIn} (profile);
%     
%     \node[node,right of=profile, node distance=1cm, fill=blue!100](itemLabel){};
%     \node[unboxed,below of=itemLabel, node distance=.5cm](itemLabelLabel){?pItemL};
%     \path[edge,below=.1pt] (profile) edge node {} (itemLabel);
%     
%     \node[node,below of=profile,node distance=1.5cm, fill=blue!10](user){U};
%     \node[unboxed,left of=user,node distance=.7cm](userLabel){?user};
%     \path[edge,left=.1pt] (user) edge node {?rel} (profile);
% 
% \node[blind,left of=queryNode,node distance=4.2cm](queryNodeLeft){}; 
% \node[blind,right of=queryNode,node	distance=3.9cm](queryNodeRight){};  
% \node[blind,above of=queryNode,node	distance=.5cm](queryNodeAbove){};    
% \node[blind,below of=queryNode,node	distance=5cm](queryNodeBelow){}; 
% \node[bigbox, fit=(queryNodeAbove)(queryNodeLeft)(queryNodeRight)(meas2Label)](where) {};
% \node[title, right=10pt, font=\Large] at (where.north west) {Where};
% 
% 	\node[node,right of=queryNode, node distance=8.1cm, fill=yellow!30,font=\small](bQueryNode){B};	
% 	
% 	\node[node, right of=bQueryNode,node distance=2.1cm, fill=red!10](dataSource){DS};
%     \path[edge,above=.1pt] (bQueryNode) edge node {dataSource} (dataSource);
%     
%     \node[node,right of=dataSource, node distance=1.2cm, fill=red!100](dataSourceLabel){};
%     \node[unboxed,right of=dataSourceLabel, node distance=.5cm](dataSourceLabelLabel){?wL};
%     \path[edge,below=.1pt] (dataSource) edge node {} (dataSourceLabel);
%     
%     \node[node,below of=bQueryNode,node distance=1.5cm, fill=yellow!10](proj1){PI};
%     \path[edge, left=.3pt] (bQueryNode) edge node {project} (proj1);
%     
%     \node[node,below of=proj1,node distance=1.5cm, fill=yellow!10](projExpression1){DE};
%     \path[edge,left=.1pt] (proj1) edge node {expression} (projExpression1);
%     
%     \node[node,below of=projExpression1,node distance=1.5cm, fill=yellow!10](dimensionReference){DR};
%     \path[edge,right=.1pt] (projExpression1) edge node {dim} (dimensionReference);
%        
%     \node[node,below of=dimensionReference, node distance=1cm, fill=red!100](dimensionReferenceLabel1){};
%     \node[unboxed,below of=dimensionReferenceLabel1, node distance=.45cm](dimensionReferenceLabelLabel1){?dL1};
%     \path[edge] (dimensionReference) edge node {name} (dimensionReferenceLabel1);
%            
% %     \node[node,left of=proj1,node distance=1.5cm, fill=yellow!10](proj2){PI};
% %     \path[edge] (bQueryNode) edge node {proj} (proj2);
%     
%     \node[node,left of=projExpression1,node distance=1.3cm, fill=yellow!10](projExpression2){ME};
%     \path[edge] (proj1) edge node {} (projExpression2);
%     
%     \node[node,below of=projExpression2,node distance=1.5cm, fill=yellow!10](measureReference){MR};
%     \path[edge,right=.1pt] (projExpression2) edge node {meas} (measureReference);
%              
%     \node[node,below of=measureReference, node distance=1cm, fill=red!100](measureReferenceLabel2){};
%     \node[unboxed,below of=measureReferenceLabel2, node distance=.45cm](measureReferenceLabelLabel2){?mL1};
%     \path[edge] (measureReference) edge node {name} (measureReferenceLabel2);
%         
% %     \node[node,left of=proj2,node distance=1.2cm, fill=yellow!10](truncation){TO};
% 	\node[node,left of=proj1,node distance=2.4cm, fill=yellow!10](truncation){TO};
%     \path[edge, dashed, left=.3pt] (bQueryNode) edge node {truncate} (truncation);  
%      
%     \node[node,below of=truncation,node distance=1.5cm, fill=yellow!10](sorting){SE};
%     \path[edge] (truncation) edge node {sorting} (sorting); 
%     
%     \path[edge, left=.1pt] (sorting) edge node {by} (measureReference);  
%            
%     \node[node,below left of=sorting, node distance=1.2cm, fill=green!100](sortingOrder){};
%     \node[unboxed,below of=sortingOrder, node distance=.45cm](sortingOrderLabel){?ord};
%     \path[edge, left=.1pt] (sorting) edge node {order} (sortingOrder);
%     
% %     \node[node,below of=sorting, node distance=1.2cm, fill=red!100](sortingBy){};
% %     \node[unboxed,below of=sortingBy, node distance=.45cm](sortingByLabel){?mL1};
% %     \path[edge, right=.1pt] (sorting) edge node {by} (sortingBy);
%         
%     \node[node,below left of=truncation, node distance=1.2cm, fill=green!100](truncationNumber){};
%     \node[unboxed,below of=truncationNumber, node distance=.45cm](truncatinNumberLabel){?nb};
%     \path[edge,left=.1pt] (truncation) edge node {limit} (truncationNumber);    
%     
%     \node[node,right of=proj1,node distance=1.3cm, fill=yellow!10](filter1){FE};
%     \path[edge, dashed] (bQueryNode) edge node {select} (filter1); 
%     
%     \node[node,below of=filter1,node distance=1.5cm, fill=yellow!10](memberSet){MS};
%     \path[edge] (filter1) edge node {membSet} (memberSet);
%     
%     \node[node,below of=memberSet,node distance=1.5cm, fill=yellow!10](memberRef){VR};
%     \path[edge,right=.1pt] (memberSet) edge node {memb} (memberRef);
%     
%     \node[node,below of=memberRef, node distance=1cm, fill=red!100](memberLabel){};
%     \node[unboxed,below of=memberLabel, node distance=.45cm](memberLabelLabel){?vL1};
%     \path[edge] (memberRef) edge node {name} (memberLabel);
%     
%     \node[node, right of=memberSet, node distance=1.1cm, fill=red!100](memberDim){};
%     \node[unboxed,below of=memberDim, node distance=.45cm](memberDimLabel){?dL2};
%     \path[edge,above=.1pt] (memberSet) edge node {type} (memberDim);
%     
%     \node[node,right of=filter1,node distance=2cm, fill=yellow!10](filter2){FE};
%     \path[edge, dashed, right=.3pt] (bQueryNode) edge node {select} (filter2);
%     
%     \node[node,below of=filter2,node distance=1.5cm, fill=yellow!10](memberSet2){MS};
%     \path[edge] (filter2) edge node {membSet} (memberSet2);
%     
%     \node[node,below of=memberSet2,node distance=1.5cm, fill=yellow!10](memberRef2){VR};
%     \path[edge,right=.1pt] (memberSet2) edge node {memb} (memberRef2);
%     
%     \node[node,below of=memberRef2, node distance=1cm, fill=blue!100](memberLabel2){};
%     \node[unboxed,below of=memberLabel2, node distance=.45cm](memberLabelLabel2){?pItemL};
%     \path[edge] (memberRef2) edge node {name} (memberLabel2);
%     
%     \node[node, right of=memberSet2, node distance=1.1cm, fill=red!100](memberDim2){};
%     \node[unboxed,below of=memberDim2, node distance=.45cm](memberDimLabel2){?dL3};
%     \path[edge,above=.1pt] (memberSet2) edge node {type} (memberDim2);
% 
% \node[blind,above of=bQueryNode,node distance=.5cm](bQueryNodeAbove){};    
% \node[blind,left of=bQueryNode,node distance=3.6cm](bQueryNodeLeft){}; 
% \node[blind,right of=bQueryNode,node distance=4.7cm](bQueryNodeRight){};
% \node[blind,below of=bQueryNode,node distance=7.85cm](bQueryNodeBelow){}; 
% \node[bigbox, fit=(bQueryNodeAbove)(bQueryNodeBelow)(bQueryNodeLeft)(bQueryNodeRight)](construct) {};
% \node[title, right=10pt, font=\Large] at (construct.north west) {Construct};
% 
% \node[below=5pt] at (where.south west) (legend1) {};
% 
% 	\node[right=1pt of legend1,minimum width=50pt]{Type Abbreviations:};
% 	\node[right=1pt of legend1,text width=100pt,minimum width=100pt,yshift=-12pt] {Q - Question Node};
% 	\node[right=1pt of legend1,text width=100pt,minimum width=100pt,yshift=-20pt] {A - Annotation};
% 	\node[right=1pt of legend1,text width=100pt,minimum width=100pt,yshift=-28pt] {M - Measure};
% 	\node[right=1pt of legend1,text width=100pt,minimum width=100pt,yshift=-36pt] {D - Dimension};
% 	\node[right=1pt of legend1,text width=100pt,minimum width=100pt,yshift=-44pt] {W - Date Warehouse};
% 	\node[right=1pt of legend1,text width=100pt,minimum width=100pt,yshift=-52pt] {P - NL Pattern};
% 	\node[right=1pt of legend1,text width=100pt,minimum width=100pt,yshift=-60pt] {U - User};
% 	\node[right=1pt of legend1,text width=100pt,minimum width=100pt,yshift=-68pt] {? - `arbitrary'};
% 	
% 	\node[right=120pt of legend1,minimum width=50pt]{Variable Abbreviations:};
% 	\node[right=120pt of legend1,text width=100pt,minimum width=100pt,yshift=-12pt] {?a$x$ - annotation \#$x$};
% 	\node[right=120pt of legend1,text width=100pt,minimum width=100pt,yshift=-20pt] {?nb  - number of items};
% 	\node[right=120pt of legend1,text width=100pt,minimum width=100pt,yshift=-28pt] {?ord - order (DESC/ASC)};
% 	\node[right=120pt of legend1,text width=100pt,minimum width=100pt,yshift=-36pt] {?d$x$ - dimension \#$x$};
% 	\node[right=120pt of legend1,text width=100pt,minimum width=100pt,yshift=-44pt] {?dL$x$ - dimension label \#$x$};
% 	\node[right=120pt of legend1,text width=100pt,minimum width=100pt,yshift=-52pt] {?vL$x$ - member label \#$x$};
% 	\node[right=120pt of legend1,text width=100pt,minimum width=100pt,yshift=-60pt] {?m$x$ - measure \#$x$};
% 	\node[right=120pt of legend1,text width=100pt,minimum width=100pt,yshift=-68pt] {?mL$x$ - measure label \#$x$};
% 	\node[right=120pt of legend1,text width=100pt,minimum width=100pt,yshift=-76pt] {?w - data warehouse};
% 	\node[right=120pt of legend1,text width=100pt,minimum width=100pt,yshift=-84pt] {?wL - warehouse label};
% 	\node[right=120pt of legend1,text width=100pt,minimum width=100pt,yshift=-92pt] {?pItemL - profile label};
% 	\node[right=120pt of legend1,text width=100pt,minimum width=100pt,yshift=-100pt] {?rel - `some relationship'};
% 
% \node[below=5pt] at (construct.south west) (legend2) {};
% 
% 	\node[right=1pt of legend2,minimum width=50pt]{Type Abbreviations:};
% 	\node[right=1pt of legend2,text width=120pt,minimum width=120pt,yshift=-12pt] {B - Structured Query};
% 	\node[right=1pt of legend2,text width=120pt,minimum width=120pt,yshift=-20pt] {DS - Data Source};
% 	\node[right=1pt of legend2,text width=120pt,minimum width=120pt,yshift=-28pt] {TO - Truncation \& Order};
% 	\node[right=1pt of legend2,text width=120pt,minimum width=120pt,yshift=-36pt] {SE - Sorting Expression};
% 	\node[right=1pt of legend2,text width=120pt,minimum width=120pt,yshift=-44pt] {PI - Projection Items};
% 	\node[right=1pt of legend2,text width=120pt,minimum width=120pt,yshift=-52pt] {ME - Measure Expression};
% 	\node[right=1pt of legend2,text width=120pt,minimum width=120pt,yshift=-60pt] {MR - Measure Reference};
% 	\node[right=1pt of legend2,text width=120pt,minimum width=120pt,yshift=-68pt] {DE - Dimension Expression};
% 	\node[right=1pt of legend2,text width=120pt,minimum width=120pt,yshift=-76pt] {DR - Dimension Reference};
% 	\node[right=1pt of legend2,text width=120pt,minimum width=120pt,yshift=-84pt] {FE - Filter Expression};
% 	\node[right=1pt of legend2,text width=120pt,minimum width=120pt,yshift=-92pt] {MS - MemberSet};
% 	\node[right=1pt of legend2,text width=120pt,minimum width=120pt,yshift=-100pt] {VR - Value Reference};
% 
% 	\node[right=120pt of legend2,minimum width=50pt]{Variable Abbreviations:};
% 	\node[right=120pt of legend2,text width=100pt,minimum width=100pt,yshift=-12pt] {?nb  - number of items};
% 	\node[right=120pt of legend2,text width=100pt,minimum width=100pt,yshift=-20pt] {?ord - order (DESC/ASC)};
% 	\node[right=120pt of legend2,text width=100pt,minimum width=100pt,yshift=-28pt] {?dL$x$ - dimension label \#$x$};
% 	\node[right=120pt of legend2,text width=100pt,minimum width=100pt,yshift=-36pt] {?vL$x$ - member label \#$x$};
% 	\node[right=120pt of legend2,text width=100pt,minimum width=100pt,yshift=-44pt] {?mL$x$ - measure label \#$x$};
% 	\node[right=120pt of legend2,text width=100pt,minimum width=100pt,yshift=-52pt] {?wL - warehouse label};
% 	\node[right=120pt of legend2,text width=100pt,minimum width=100pt,yshift=-60pt] {?pItemL - profile label};
% 
% \end{tikzpicture}
% \end{center}
\includegraphics[scale=0.9]{img/pattern}
% \vspace{-.5cm}
\caption{Example for parse graph constraints and mapping rules to generate a
structrued query (see figure~\ref{fig:translation-process})}
\vspace{-.5cm}
\label{fig:structural-constraints}
\end{figure*}


% 